package org.phalanx.servlet;

import java.io.IOException;
import java.net.URL;
import javax.servlet.ServletConfig;
import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.phalanx.logger.SystemLogger;
import org.phalanx.server.PhalanxServer;
import org.phalanx.server.ServerCache.CacheManager;
import org.phalanx.server.game.PhalanxBattleRPGEngine;
import org.phalanx.server.io.PhalanxServerFileLoader;
import org.phalanx.servlet.webmessages.AuthenticationContext;
import org.phalanx.servlet.webmessages.ChatRoomContext;
import org.phalanx.servlet.webmessages.FeedListener;
import org.phalanx.servlet.webmessages.GamesChatInfoContext;
import org.phalanx.servlet.webmessages.MapMediaLoaderContext;
import org.phalanx.servlet.webmessages.PhalanxGameContext;
import org.phalanx.servlet.webmessages.PhalanxGameStateContext;
import org.phalanx.servlet.webmessages.PhalanxMapLoaderContext;
import org.phalanx.servlet.webmessages.TestContext;
import org.phalanx.servlet.webmessages.WebContextMessageManager;
import org.phalanx.servlet.websession.JoinFeedCacheHandler;
import org.phalanx.servlet.websession.ServerThreadLoader;

public class PhalanxServletLoader extends HttpServlet {

	private static SystemLogger servletLogger = new SystemLogger(SystemLogger.NORMAL);
	private static PhalanxServer pServer;
	/**
	 * 
	 */
	private static final long serialVersionUID = -6391328294966380994L;

	@Override
	protected void doGet(HttpServletRequest req, HttpServletResponse resp)
			throws ServletException, IOException {
		if (req.getParameter("context") != null){
			String context = req.getParameter("context");
			Cookie authCookie = getSessionCookie(req);
			
			
			getContextGetListeners().sendContextToListeners(context, authCookie, req, resp);
		} // context is not null
	}

	@Override
	protected void doPost(HttpServletRequest req, HttpServletResponse resp)
			throws ServletException, IOException {
		// First check to see if message is for authentication

		if (req.getParameter("context") != null){
			String context = req.getParameter("context").toString();
			Cookie authCookie = this.getSessionCookie(req);
			
			getContextPostListeners().sendContextToListeners(context, authCookie, req, resp);
		}
	}
	
	private boolean createPhalanxServerInit(){
		String phalanxServerFile = "";
		URL phalanxServerURL = this.getClass().getResource("/phalanxserver.xml");
		
		if (phalanxServerURL != null){
			phalanxServerFile = phalanxServerURL.getPath();
		}
			
		
		if (phalanxServerFile.isEmpty()){
			PhalanxServer.setServerInstance(new PhalanxServer());
		} 
		else {
			PhalanxServer.setServerInstance(new PhalanxServer(phalanxServerFile));
		}
		
		pServer = PhalanxServer.getServerInstance();
				
		return pServer != null;
	}

	@Override
	public void init(ServletConfig config) throws ServletException {
		// Create logging exclusively for servlet
		servletLogger.writeToConsole("Phalanx Servlet Service initializing...", this, SystemLogger.NORMAL);
		
		// Create PhalanxServer and check if successful
		if (createPhalanxServerInit()){
			servletLogger.writeToConsole("Core server created successfully", this, SystemLogger.NORMAL);
			servletLogger.writeToConsole("Handing off server loading to core server", this, SystemLogger.NORMAL);
			new ServerThreadLoader(pServer).startServer();
		}
		else {
			servletLogger.writeToConsole("Core server failed to load...aborting launch", this, SystemLogger.NORMAL);
		}
		
		servletLogger.writeToConsole("Waiting for Cache Loading", this, SystemLogger.NORMAL);
		handleServletCache();
		
		super.init(config);
	}
	
	private void handleServletCache(){
		
		while (!pServer.isCachesLoaded()){ // Wait until caches are fully loaded
		}

		CacheManager cacheMgr = pServer.getCacheManager();

		servletLogger.writeToConsole("Populating servlet specific caches", this, SystemLogger.NORMAL);

		cacheMgr.createNewCache("JoinFeedCache", true, new JoinFeedCacheHandler(), true);
		
		cacheMgr.populateCache("JoinFeedCache");
	}
	
	private WebContextMessageManager getContextGetListeners(){
		WebContextMessageManager contextListener = new WebContextMessageManager();
		
		contextListener.addContextListener(new FeedListener(pServer));
		contextListener.addContextListener(new TestContext(pServer));
		contextListener.addContextListener(new GamesChatInfoContext(pServer));
		contextListener.addContextListener(new MapMediaLoaderContext(pServer));
		contextListener.addContextListener(new PhalanxMapLoaderContext(pServer));
		contextListener.addContextListener(new PhalanxGameContext(pServer));
		
		return contextListener;
	}
	
	private WebContextMessageManager getContextPostListeners(){
		WebContextMessageManager contextListener = new WebContextMessageManager();
		
		contextListener.addContextListener(new AuthenticationContext(pServer));
		contextListener.addContextListener(new ChatRoomContext(pServer.getChatManager(), pServer.getCacheManager()));
		contextListener.addContextListener(new PhalanxGameContext(pServer));
		
		return contextListener;
	}

	private Cookie getSessionCookie(HttpServletRequest req){
		Cookie sessionCookie = null;
		
		Cookie[] list = req.getCookies();

		if (list != null){
			for (int i = 0; i < list.length; i++){
				Cookie tempCookie = list[i];

				if (tempCookie.getName().equals("phalanxsessionid")){
					sessionCookie = tempCookie;
					break;
				}
			}
		}
		
		return sessionCookie;
	}
}
